package com.demo.testversion1

import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.delay
import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.yield
import org.junit.Test

/**
 * Created by zhangyuncai on 2025/1/18.
 * 描述：
 */
class CoroutineTest02 {
    @Test
    fun `test scope cancel`(): Unit = runBlocking {
        val scope = CoroutineScope((Dispatchers.Default))
        scope.launch {
            try {
                delay(1000)//如果不try,默认自处理异常
            } catch (e: Exception) {
                e.printStackTrace()
            }
            println("job 1")
        }
        val job = scope.launch {
            delay(1000)
            println("job 2")
        }
//        job.cancelAndJoin()
        /*
        由于CoroutineScope有自己的上下文没有继承runBlocking上下文
        ,所以必须添加这行代码才会纸吸管
         */
        delay(100)
        scope.cancel(CancellationException("取消了"))
    }

    @Test
    fun `test cancel cpu task by is Active`(): Unit = runBlocking {
        val startTime = System.currentTimeMillis()
        val job = launch(Dispatchers.Default) {
            var nextPrintTime = startTime
            var i = 0
//            while (i < 5) {
//                if (System.currentTimeMillis() >= nextPrintTime) {//CPU密集型任务,无法取消
//                    println("sleep${i++}")
//                    nextPrintTime += 500
//                }
//            }
            while (i < 5 && isActive) {
                if (System.currentTimeMillis() >= nextPrintTime) {//所以通过isActive
                    println("sleep${i++}")
                    nextPrintTime += 500
                }
            }

        }
        delay(1300)
        println("waiting")
        job.cancelAndJoin()
        println("quit")
    }

    @Test
    fun `test cancel cpu task by ensureActive`(): Unit = runBlocking {
        val startTime = System.currentTimeMillis()
        val job = launch(Dispatchers.Default) {
            var nextPrintTime = startTime
            var i = 0
//            while (i < 5) {
//                if (System.currentTimeMillis() >= nextPrintTime) {//CPU密集型任务,无法取消
//                    println("sleep${i++}")
//                    nextPrintTime += 500
//                }
//            }
            while (i < 5) {
                ensureActive()//所以通过ensureActive取消密集型任务
                if (System.currentTimeMillis() >= nextPrintTime) {//
                    println("sleep${i++}")
                    nextPrintTime += 500
                }
            }

        }
        delay(1300)
        println("waiting")
        job.cancelAndJoin()
        println("quit")
    }

    @Test
    fun `test cancel cpu task by yield`(): Unit = runBlocking {
        val startTime = System.currentTimeMillis()
        val job = launch(Dispatchers.Default) {
            var nextPrintTime = startTime
            var i = 0
//            while (i < 5) {
//                if (System.currentTimeMillis() >= nextPrintTime) {//CPU密集型任务,无法取消
//                    println("sleep${i++}")
//                    nextPrintTime += 500
//                }
//            }
            while (i < 5) {
                yield()//取消后静默退出,会抛异常,并尝试出让线程权
                if (System.currentTimeMillis() >= nextPrintTime) {//
                    println("sleep${i++}")
                    nextPrintTime += 500
                }
            }

        }
        delay(1300)
        println("waiting")
        job.cancelAndJoin()
        println("quit")
    }
}